"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const cluster_1 = tslib_1.__importDefault(require("cluster"));
const os_1 = require("os");
const pidManager_1 = require("./pidManager");
class default_1 {
    /**
     * @param options 启动配置
     * @param MAX_RETRY 最多可重试次数
     */
    constructor(options, maxRetry = 5) {
        this.interval = -1;
        this.exitInterval = -1;
        /** 重试次数 */
        this.retried = 0;
        /** 是否通知父进程 */
        this.IS_NOTIFY = false;
        this.options = options;
        this.MAX_RETRY = maxRetry;
    }
    /**
     * 启动
     * @param scriptFile 脚本文件地址
     */
    async setup(scriptFile) {
        if (cluster_1.default.isMaster) {
            const count = this.getMaxWorkers();
            for (let i = 0; i < count; i++) {
                cluster_1.default.fork();
            }
            cluster_1.default.on('exit', () => {
                this.canExit();
                clearTimeout(this.interval);
                if (this.retried <= this.MAX_RETRY) {
                    this.retried++;
                    cluster_1.default.fork();
                }
            });
            cluster_1.default.on('message', (worker, msg) => {
                if (!this.IS_NOTIFY) {
                    process.send && process.send(msg);
                    this.IS_NOTIFY = true;
                }
            });
            await pidManager_1.startAndWritePid({ id: this.options.id || '', pid: process.pid });
        }
        else {
            const fn = await Promise.resolve().then(() => tslib_1.__importStar(require(scriptFile)));
            fn.default(this.options);
            this.reset();
        }
    }
    /**
     * 最多启用两个worker
     */
    getMaxWorkers() {
        return os_1.cpus().length > 1 ? 2 : 1;
    }
    /**
     * 5秒内没有触发exit，则认为成功启动worker
     */
    reset() {
        clearTimeout(this.exitInterval);
        this.interval = setTimeout(() => {
            this.retried = 0;
        }, 5000);
    }
    canExit() {
        this.exitInterval = setTimeout(() => {
            if (Object.keys(cluster_1.default.workers).length === 0) {
                process.exit();
            }
        }, 5000);
    }
}
exports.default = default_1;
